<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 流年 <liu21st@gmail.com>
// +----------------------------------------------------------------------

// 应用公共文件
error_reporting(E_ERROR | E_WARNING | E_PARSE);//规避非致命错误提示，如未定义的变量
// error_reporting(E_ALL & ~E_NOTICE);
// error_reporting(0);

 /**
 *   实现中文字串截取无乱码的方法
 */
function getSubstr($string, $start, $length) {
  if(mb_strlen($string,'utf-8')>$length){
      $str = mb_substr($string, $start, $length,'utf-8');
      return $str.'...';
  }else{
      return $string;
  }
}

/**
 * @param $arr
 * @param $key_name
 * @return array
 * 将数据库中查出的列表以指定的 id 作为数组的键名
 */
function convert_arr_key($arr, $key_name)
{
    $arr2 = array();
    foreach($arr as $key => $val){
        $arr2[$val[$key_name]] = $val;
    }
    return $arr2;
}

function encrypt($str){
    return md5(config('auth_code').$str);
}

//php获取中文字符拼音首字母
function getFirstCharter($str){
    if(empty($str))
    {
        return '';
    }
    $fchar=ord($str{0});
    if($fchar>=ord('A')&&$fchar<=ord('z')) return strtoupper($str{0});
    $s1=iconv('UTF-8','gb2312',$str);
    $s2=iconv('gb2312','UTF-8',$s1);
    $s=$s2==$str?$s1:$str;
    $asc=ord($s{0})*256+ord($s{1})-65536;
    if($asc>=-20319&&$asc<=-20284) return 'A';
    if($asc>=-20283&&$asc<=-19776) return 'B';
    if($asc>=-19775&&$asc<=-19219) return 'C';
    if($asc>=-19218&&$asc<=-18711) return 'D';
    if($asc>=-18710&&$asc<=-18527) return 'E';
    if($asc>=-18526&&$asc<=-18240) return 'F';
    if($asc>=-18239&&$asc<=-17923) return 'G';
    if($asc>=-17922&&$asc<=-17418) return 'H';
    if($asc>=-17417&&$asc<=-16475) return 'J';
    if($asc>=-16474&&$asc<=-16213) return 'K';
    if($asc>=-16212&&$asc<=-15641) return 'L';
    if($asc>=-15640&&$asc<=-15166) return 'M';
    if($asc>=-15165&&$asc<=-14923) return 'N';
    if($asc>=-14922&&$asc<=-14915) return 'O';
    if($asc>=-14914&&$asc<=-14631) return 'P';
    if($asc>=-14630&&$asc<=-14150) return 'Q';
    if($asc>=-14149&&$asc<=-14091) return 'R';
    if($asc>=-14090&&$asc<=-13319) return 'S';
    if($asc>=-13318&&$asc<=-12839) return 'T';
    if($asc>=-12838&&$asc<=-12557) return 'W';
    if($asc>=-12556&&$asc<=-11848) return 'X';
    if($asc>=-11847&&$asc<=-11056) return 'Y';
    if($asc>=-11055&&$asc<=-10247) return 'Z';
    return null;
}


/**
 * 获取缓存或者更新缓存
 * @param string $config_key 缓存文件名称
 * @param array $data 缓存数据  array('k1'=>'v1','k2'=>'v3')
 * @return array or string or bool
 */
function tpCache($config_key,$data = array()){
    $param = explode('.', $config_key);
    // if(empty($data)){
        //如$config_key=shop_info则获取网站信息数组
        //如$config_key=shop_info.logo则获取网站logo字符串
        // $config = F($param[0],'',TEMP_PATH);//直接获取缓存文件
        // if(empty($config)){
            //缓存文件不存在就读取数据库
            $res = db('config')->where("inc_type='$param[0]'")->select();
            if($res){
                foreach($res as $k=>$val){
                    $config[$val['name']] = $val['value'];
                }
                // F($param[0],$config,TEMP_PATH);
            }
        // }
        if(count($param)>1){
            return $config[$param[1]];
        }else{
            return $config;
        }
    // }
    
}

/*
utf-8编码下截取中文字符串,参数可以参照substr函数
@param $str 要进行截取的字符串
@param $start 要进行截取的开始位置，负数为反向截取
@param $end 要进行截取的长度
*/
function utf8_substr($str,$start=0,$end) {
    if(empty($str)){
        return false;
    }
    if (function_exists('mb_substr')){
        if(func_num_args() >= 3) {
            $end = func_get_arg(2);
            return mb_substr($str,$start,$end,'utf-8');
        }
        else {
            mb_internal_encoding("UTF-8");
            return mb_substr($str,$start);
        }      
 
    }
    else {
        $null = "";
        preg_match_all("/./u", $str, $ar);
        if(func_num_args() >= 3) {
            $end = func_get_arg(2);
            return join($null, array_slice($ar[0],$start,$end));
        }
        else {
            return join($null, array_slice($ar[0],$start));
        }
    }
}
/**
* 可以统计中文字符串长度的函数
* @param $str 要计算长度的字符串
* @param $type 计算长度类型，0(默认)表示一个中文算一个字符，1表示一个中文算两个字符
*
*/
function abslength($str)
{
    if(empty($str)){
        return 0;
    }
    if(function_exists('mb_strlen')){
        // return 123;
        // function_exists 检查函数是否已定义
        return mb_strlen($str,'utf-8');
    }
    else {
        // return 235;
        preg_match_all("/./u", $str, $ar);
        return count($ar[0]);
    }
}
/**
 * 字符串超出长度尾部追加省略号
 */
function subtext($text, $length){
    // return abslength($text);
    if(abslength($text) > $length){
        return utf8_substr($text, 0, $length).'...';
    }
    return $text;
}
function sub_text($text, $length){
    // return abslength($text);
    if(abslength($text) > $length){
        return utf8_substr($text, 0, $length);
    }
    return $text;
}

//过滤html标签
function movehtml($_obfuscate_R2_b,$_obfuscate_KT_ujQ = false){
    if($_obfuscate_KT_ujQ){
        $_obfuscate_dcwit = array( "/<img[^\\<\\>]+src=['\"]?([^\\<\\>'\"\\s]*)['\"]?/is", "/<a[^\\<\\>]+href=['\"]?([^\\<\\>'\"\\s]*)['\"]?/is", "/on[a-z]+[\\s]*=[\\s]*\"[^\"]*\"/is", "/on[a-z]+[\\s]*=[\\s]*'[^']*'/is" );
        $_obfuscate_77tGbWOiZg   = array( "\\1<br>\\0", "\\1<br>\\0", "", "" );
        $_obfuscate_R2_b = preg_replace( $_obfuscate_dcwit, $_obfuscate_77tGbWOiZg  , $_obfuscate_R2_b );
    }
    $_obfuscate_dcwit = array( "/([\r\n])[\\s]+/", "/\\<br[^\\>]*\\>/i", "/\\<[\\s]*\\/p[\\s]*\\>/i", "/\\<[\\s]*p[\\s]*\\>/i", "/\\<script[^\\>]*\\>.*\\<\\/script\\>/is", "/\\<[\\/\\!]*[^\\<\\>]*\\>/is", "/&(quot|#34);/i", "/&(amp|#38);/i", "/&(lt|#60);/i", "/&(gt|#62);/i", "/&(nbsp|#160);/i", "/&#(\\d+);/", "/&([a-z]+);/i" );
    $_obfuscate_77tGbWOiZg = array( " ", "\r\n", "", "\r\n\r\n", "", "", "\"", "&", "<", ">", " ", "-", "" );
    $_obfuscate_R2_b = preg_replace( $_obfuscate_dcwit, $_obfuscate_77tGbWOiZg  , $_obfuscate_R2_b );
    $_obfuscate_R2_b = htmlspecialchars_decode($_obfuscate_R2_b);
    $_obfuscate_R2_b = strip_tags( $_obfuscate_R2_b );
    return $_obfuscate_R2_b;
}

 // 定义一个函数getIP() 客户端IP，
function getIP(){
    if (getenv("HTTP_CLIENT_IP"))
        $ip = getenv("HTTP_CLIENT_IP");
    else if(getenv("HTTP_X_FORWARDED_FOR"))
        $ip = getenv("HTTP_X_FORWARDED_FOR");
    else if(getenv("REMOTE_ADDR"))
        $ip = getenv("REMOTE_ADDR");
    else $ip = "Unknow";
    return $ip;
}
// 服务器端IP
function serverIP(){
    return gethostbyname($_SERVER["SERVER_NAME"]);
}



/**
 * 数组 转 对象
 *
 * @param array $arr 数组
 * @return object
 */
function array_to_object($arr) {
    if (gettype($arr) != 'array') {
        return;
    }
    foreach ($arr as $k => $v) {
        if (gettype($v) == 'array' || getType($v) == 'object') {
            $arr[$k] = (object)array_to_object($v);
        }
    }
 
    return (object)$arr;
}
 
/**
 * 对象 转 数组
 *
 * @param object $obj 对象
 * @return array
 */
function object_to_array($obj) {
    $obj = (array)$obj;
    foreach ($obj as $k => $v) {
        if (gettype($v) == 'resource') {
            return;
        }
        if (gettype($v) == 'object' || gettype($v) == 'array') {
            $obj[$k] = (array)object_to_array($v);
        }
    }
 
    return $obj;
}

//判断终端类型
function is_mobile() { 
    if (isset($_SERVER['HTTP_VIA'])) return true; 
    if (isset($_SERVER['HTTP_X_NOKIA_CONNECTION_MODE'])) return true; 
    if (isset($_SERVER['HTTP_X_UP_CALLING_LINE_ID'])) return true; 
    if (strpos(strtoupper($_SERVER['HTTP_ACCEPT']),"VND.WAP.WML") > 0) { 
    // Check whether the browser/gateway says it accepts WML. 
    $br = "WML"; 
    } else { 
    $browser = isset($_SERVER['HTTP_USER_AGENT']) ? trim($_SERVER['HTTP_USER_AGENT']) : ''; 
    if(empty($browser)) return true; 
    $mobile_os_list=array('Google Wireless Transcoder','Windows CE','WindowsCE','Symbian','Android','armv6l','armv5','Mobile','CentOS','mowser','AvantGo','Opera Mobi','J2ME/MIDP','Smartphone','Go.Web','Palm','iPAQ'); 
    $mobile_token_list=array('Profile/MIDP','Configuration/CLDC-','160×160','176×220','240×240','240×320','320×240','UP.Browser','UP.Link','SymbianOS','PalmOS','PocketPC','SonyEricsson','Nokia','BlackBerry','Vodafone','BenQ','Novarra-Vision','Iris','NetFront','HTC_','Xda_','SAMSUNG-SGH','Wapaka','DoCoMo','iPhone','iPod'); 
    $found_mobile=checkSubstrs($mobile_os_list,$browser) || 
    checkSubstrs($mobile_token_list,$browser); 
    if($found_mobile) 
    $br ="WML"; 
    else $br = "WWW"; 
    } 
    if($br == "WML") { 
    return true; 
    } else { 
    return false; 
    } 
} 

function checkSubstrs($list,$str){ 
    $flag = false; 
    for($i=0;$i<count($list);$i++){ 
        if(strpos($str,$list[$i]) > 0){ 
            $flag = true; 
            break; 
        } 
    } 
    return $flag; 
}
//截取指定2个字符之间字符串的方法
function getNeedBetween($kw1,$mark1,$mark2){
    $kw=$kw1;
    $kw='123'.$kw.'123';
    $st =stripos($kw,$mark1);
    $ed =stripos($kw,$mark2);
    if(($st==false||$ed==false)||$st>=$ed)
        return 0;
    $kw=substr($kw,($st+1),($ed-$st-1));
    return $kw;
}

/*
$array:需要排序的数组
$keys:需要根据某个key排序
$sort:倒叙还是顺序
*/
function arraySort($array,$keys,$sort='asc') {
    $newArr = $valArr = array();
    foreach ($array as $key=>$value) {
        $valArr[$key] = $value[$keys]; 
    }
    ($sort == 'asc') ?  asort($valArr) : arsort($valArr);//先利用keys对数组排序，目的是把目标数组的key排好序
    reset($valArr); //指针指向数组第一个值 
    foreach($valArr as $key=>$value) {
        $newArr[$key] = $array[$key];
    }
    return $newArr;
}

function echojson($status,$msg,$data=''){
    $array = [
        'status' => $status,
        'msg' => $msg,
        'message' => $msg,
        'data' => $data,
    ];
    return json_encode($array);
}

function exitjson($status,$msg,$data=''){
    $array = [
        'status' => $status,
        'msg' => $msg,
        'message' => $msg,
        'data' => $data,
    ];
    echo json_encode($array);exit;
}

function HttpPost($url,$param){

    $ch = curl_init();
    //如果$param是数组的话直接用
    curl_setopt($ch, CURLOPT_URL, $url);
    //如果$param是json格式的数据，则打开下面这个注释
    // curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    //         'Content-Type: application/json',
    //         'Content-Length: ' . strlen($param))
    // );
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    //如果用的协议是https则打开鞋面这个注释
    // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    // curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

    $data = curl_exec($ch);

    curl_close($ch);
    return $data;

}

/*
* array unique_rand( int $min, int $max, int $num )
* 生成一定数量的不重复随机数，指定的范围内整数的数量必须
* 比要生成的随机数数量大
* $min 和 $max: 指定随机数的范围
* $num: 指定生成数量
*/
function unique_rand($min, $max, $num , $isadd=false) {
  $count = 0;
  $return = array();
  while ($count < $num) {
    if($isadd){
        $str = '';
        for($i=0;$i<8;$i++){
            $str .= chr(rand(97,122));
        }
        $return[] = $str.str_pad(mt_rand($min, $max), 10, '0', STR_PAD_LEFT);
    }else{
        $return[] = mt_rand($min, $max);
    }
    $return = array_flip(array_flip($return));
    $count = count($return);
  }
  //打乱数组，重新赋予数组新的下标
  shuffle($return);
  return $return;
}



function get_os($agent) {
    $os = false;
    if (preg_match('/win/i', $agent) && strpos($agent, '95')) {
        $os = 'Windows 95';
    } else if (preg_match('/win 9x/i', $agent) && strpos($agent, '4.90')) {
        $os = 'Windows ME';
    } else if (preg_match('/win/i', $agent) && preg_match('/98/i', $agent)) {
        $os = 'Windows 98';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 6.0/i', $agent)) {
        $os = 'Windows Vista';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 6.1/i', $agent)) {
        $os = 'Windows 7';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 6.2/i', $agent)) {
        $os = 'Windows 8';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 10.0/i', $agent)) {
        $os = 'Windows 10';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 5.1/i', $agent)) {
        $os = 'Windows XP';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 5/i', $agent)) {
        $os = 'Windows 2000';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt/i', $agent)) {
        $os = 'Windows NT';
    } else if (preg_match('/win/i', $agent) && preg_match('/32/i', $agent)) {
        $os = 'Windows 32';
    } else if (preg_match('/linux/i', $agent)) {
        if (preg_match("/Mobile/", $agent)) {
            if (preg_match("/QQ/i", $agent)) {
                $os = "Android QQ Browser";
            } else {
                $os = "Android Browser";
            }
        } else {
            $os = 'PC-Linux';
        }
    } else if (preg_match('/Mac/i', $agent)) {
        if (preg_match("/Mobile/", $agent)) {
            if (preg_match("/QQ/i", $agent)) {
                $os = "IPhone QQ Browser";
            } else {
                $os = "IPhone Browser";
            }
        } else {
            $os = 'Mac OS X';
        }
    } else if (preg_match('/unix/i', $agent)) {
        $os = 'Unix';
    } else if (preg_match('/sun/i', $agent) && preg_match('/os/i', $agent)) {
        $os = 'SunOS';
    } else if (preg_match('/ibm/i', $agent) && preg_match('/os/i', $agent)) {
        $os = 'IBM OS/2';
    } else if (preg_match('/Mac/i', $agent) && preg_match('/PC/i', $agent)) {
        $os = 'Macintosh';
    } else if (preg_match('/PowerPC/i', $agent)) {
        $os = 'PowerPC';
    } else if (preg_match('/AIX/i', $agent)) {
        $os = 'AIX';
    } else if (preg_match('/HPUX/i', $agent)) {
        $os = 'HPUX';
    } else if (preg_match('/NetBSD/i', $agent)) {
        $os = 'NetBSD';
    } else if (preg_match('/BSD/i', $agent)) {
        $os = 'BSD';
    } else if (preg_match('/OSF1/i', $agent)) {
        $os = 'OSF1';
    } else if (preg_match('/IRIX/i', $agent)) {
        $os = 'IRIX';
    } else if (preg_match('/FreeBSD/i', $agent)) {
        $os = 'FreeBSD';
    } else if (preg_match('/teleport/i', $agent)) {
        $os = 'teleport';
    } else if (preg_match('/flashget/i', $agent)) {
        $os = 'flashget';
    } else if (preg_match('/webzip/i', $agent)) {
        $os = 'webzip';
    } else if (preg_match('/offline/i', $agent)) {
        $os = 'offline';
    } else {
        $os = '未知操作系统';
    }
    return $os;
}

function get_broswer($sys) {
    if (stripos($sys, "Firefox/") > 0) {
        preg_match("/Firefox\/([^;)]+)+/i", $sys, $b);
        $exp[0] = "Firefox";
        $exp[1] = $b[1];
    }
    elseif(stripos($sys, "Maxthon") > 0) {
        preg_match("/Maxthon\/([\d\.]+)/", $sys, $aoyou);
        $exp[0] = "傲游";
        $exp[1] = $aoyou[1];
    }
    elseif(stripos($sys, "MSIE") > 0) {
        preg_match("/MSIE\s+([^;)]+)+/i", $sys, $ie);
        $exp[0] = "IE";
        $exp[1] = $ie[1];
    }
    elseif(stripos($sys, "OPR") > 0) {
        preg_match("/OPR\/([\d\.]+)/", $sys, $opera);
        $exp[0] = "Opera";
        $exp[1] = $opera[1];
    }
    elseif(stripos($sys, "Edge") > 0) {
        preg_match("/Edge\/([\d\.]+)/", $sys, $Edge);
        $exp[0] = "Edge";
        $exp[1] = $Edge[1];
    }
    elseif(stripos($sys, "Chrome") > 0) {
        preg_match("/Chrome\/([\d\.]+)/", $sys, $google);
        $exp[0] = "Chrome";
        $exp[1] = $google[1];
    }
    elseif(stripos($sys, 'rv:') > 0 && stripos($sys, 'Gecko') > 0) {
        preg_match("/rv:([\d\.]+)/", $sys, $IE);
        $exp[0] = "IE";
        $exp[1] = $IE[1];
    } else {
        $exp[0] = "未知浏览器";
        $exp[1] = "";
    }
    return $exp[0].
    '('.$exp[1].
    ')';
}

function get_address_by_ip($ip) {
    $url = "http://ip.taobao.com/service/getIpInfo.php?ip=".$ip;
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    $info = curl_exec($curl);
    curl_close($curl);
    return $info;
}

function array_elements($keys, $src, $default = FALSE) {
    $return = array();
    if(!is_array($keys)) {
        $keys = array($keys);
    }
    foreach($keys as $key) {
        if(isset($src[$key])) {
            $return[$key] = $src[$key];
        } else {
            $return[$key] = $default;
        }
    }
    return $return;
}

function addlog($data, $type="", $file_name=""){
    $str = date("Y-m-d H:i:s");
    if( !empty($type) ){
        $str .= " ".$type;
    }
    if( is_array($data) ){
        $data = json_encode($data);
    }else if( is_object($data) ){
        $data = json_encode( (array)$data );
    }
    $str .= " : ".$data;
    $path = $_SERVER['DOCUMENT_ROOT'].'/runtime/logs/'.date("Ym");
    if( !is_dir($path) ){
        mkdir( $path."/", 0777, true );
    }
    $file_name = empty($file_name) ? date('d') : $file_name;
    file_put_contents($path."/".$file_name.'.log', $str.PHP_EOL, FILE_APPEND );
}

function post_url($url, $postData = false, $header = false) {
    $ch = curl_init($url);
    curl_setopt($ch,CURLOPT_HEADER,0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //返回数据不直接输出
    curl_setopt($ch, CURLOPT_ENCODING, "gzip"); //指定gzip压缩
    //add header
    if(!empty($header)) {
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    }
    //add ssl support
    if(substr($url, 0, 5) == 'https') {
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);    //SSL 报错时使用
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);    //SSL 报错时使用
    }
    //add 302 support
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    // curl_setopt($ch,CURLOPT_COOKIEFILE, $this->lastCookieFile); //使用提交后得到的cookie数据
    //add post data support
    if(!empty($postData)) {
        curl_setopt($ch,CURLOPT_POST, 1);
        curl_setopt($ch,CURLOPT_POSTFIELDS, $postData);
    }
    try {
        $content = curl_exec($ch); //执行并存储结果
    } catch (\Exception $e) {
        // $this->_log($e->getMessage());
        // addlog($e->getMessage(),'post_url1');
    }
    $curlError = curl_error($ch);
    if(!empty($curlError)) {
        // $this->_log($curlError);
        // addlog($curlError,'post_url2');
    }
    curl_close($ch);
    return $content;
}

/**
 * php利用fsockopen异步请求
 */
function request_by_fsockopen($url,$post_data=array()){
    $url_array = parse_url($url);
    $hostname = $url_array['host'];
    $port = isset($url_array['port'])? $url_array['port'] : 80; 
    $requestPath = $url_array['path'] ."?". $url_array['query'];
    $fp = fsockopen($hostname, $port, $errno, $errstr, 10);
    if (!$fp) {
        echo "$errstr ($errno)";
        return false;
    }
    $method = "GET";
    if(!empty($post_data)){
        $method = "POST";
    }
    $header = "$method $requestPath HTTP/1.1\r\n";
    $header.="Host: $hostname\r\n";
    if(!empty($post_data)){
        $_post = strval(NULL);
        foreach($post_data as $k => $v){
                $_post[]= $k."=".urlencode($v);//必须做url转码以防模拟post提交的数据中有&符而导致post参数键值对紊乱
        }
        $_post = implode('&', $_post);
        $header .= "Content-Type: application/x-www-form-urlencoded\r\n";//POST数据
        $header .= "Content-Length: ". strlen($_post) ."\r\n";//POST数据的长度
        $header.="Connection: Close\r\n\r\n";//长连接关闭
        $header .= $_post; //传递POST数据
    }else{
        $header.="Connection: Close\r\n\r\n";//长连接关闭
    }
    fwrite($fp, $header);
    // 打开此调试，则必须等待响应返回，程序才往下执行，等效于同步
    //-----------------调试代码区间-----------------
    /*$html = '';   
    while (!feof($fp)) {
        $html.=fgets($fp);
    }
    echo $html;*/
    //-----------------调试代码区间-----------------
    fclose($fp);
}
